package com.voxel.sense.infomsg.module.map.monitor.traceRecord;

import android.graphics.Color;
import android.location.Location;
import android.os.Environment;

import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.PolylineOptions;
import com.amap.api.trace.LBSTraceClient;
import com.amap.api.trace.TraceListener;
import com.amap.api.trace.TraceLocation;
import com.example.com.common.app.BasePresenter;
import com.example.com.common.factory.data.DataSource;
import com.example.com.common.utils.FileUtils;
import com.example.com.common.utils.L;
import com.example.com.common.utils.NetworkUtils;
import com.example.com.common.utils.ToastUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;

import cyy.example.com.facotry.Factory;
import cyy.example.com.facotry.model.api.BaseEntity;
import cyy.example.com.facotry.model.api.response.TraceListEntity;
import cyy.example.com.facotry.share.SPEngine;

/**
 * Created by ChenYiYao on 2018/5/7.
 */

public class TracePresenter extends BasePresenter<TraceContract.View> implements TraceContract.Presenter, DataSource.Callback<BaseEntity> {

    private List<LatLng> mLatLngList;
    private List<LatLng> mNewLatLngs;
    private List<TraceLocation> mPrepareLatLngs;
    private TraceListEntity mEntities;
    private PolylineOptions mPolyoptions;
//    private double mOldLatitude = 0;
//    private double mOldlongitude = 0;

    private boolean record_flag = false;
    private boolean start_up = false;

    private List<TraceLocation> mTraceList;
    private LBSTraceClient mLbsTraceClient;

    private final static int TRACE_ID = 100;

    public TracePresenter(TraceContract.View view) {
        super(view);
    }

    @Override
    public void start() {
        super.start();
        mNewLatLngs = new ArrayList<>();
        mLatLngList = new ArrayList<>();
        mPrepareLatLngs = new ArrayList<>();
        mTraceList = new ArrayList<>();
        mEntities = new TraceListEntity();
        mEntities.coordinates = new ArrayList<>();

        try {
            mLbsTraceClient = LBSTraceClient.getInstance(Factory.app().getApplicationContext());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void doRecordTrace() {
        if (mPolyoptions == null) {
            mPolyoptions = new PolylineOptions();
            mPolyoptions.width(10);
            mPolyoptions.color(Color.GREEN);
        }
        record_flag = true;
//        Factory.app().startService(new Intent((Context) mView, LocationService.class));
    }

    @Override
    public void doStopRecord() {
        record_flag = false;
//        Factory.app().getApplicationContext().stopService(new Intent((Context) mView, LocationService.class));

        List<LatLng> points = mPolyoptions.getPoints();
        if (points != null && points.size() > 0) {
            LatLng latLng = points.get(points.size() - 1);
            TraceListEntity entity = new TraceListEntity();
            entity.coordinates = new ArrayList<>();
            TraceListEntity.Coordinates data = new TraceListEntity.Coordinates();
            data.latitude = latLng.latitude;
            data.longitude = latLng.longitude;
            data.dataTime = System.currentTimeMillis();
            entity.coordinates.add(data);
            entity.isEnd = "1";
            entity.userId = SPEngine.getSPEngine().getUserInfo().getUser_id();
            mEntities.coordinates.addAll(entity.coordinates);
//            NetHelper.UpTrance(entity, this);
        }
    }

    @Override
    public void doUpMyLocaton(Location location) {
        if (!record_flag)
            return;
        double latitude = location.getLatitude();
        double longitude = location.getLongitude();


        //上传位置
        if (!(0 == latitude && 0 == longitude)) {
            LatLng l = new LatLng(latitude, longitude);
            mLatLngList.add(l);
            mNewLatLngs.add(l);
//            mOldlongitude = longitude;
//            mOldLatitude =latitude;
            /**
             * 1.当坐标点达到30个后，进行位置纠偏，且上传
             * 2.在上传过程中，同时也记录坐标放在mPrepareLatLngs集合中，当上传成完成，清空mTraceList集合后，将mPrepareLatLngs数据插入到mTraceList中
             */

            TraceLocation traceLocation = new TraceLocation();
            traceLocation.setBearing(location.getBearing());
            traceLocation.setSpeed(location.getSpeed());
            traceLocation.setLatitude(location.getLatitude());
            traceLocation.setLongitude(location.getLongitude());

            //判断是否有网络
            if (NetworkUtils.isConnected()) {
                //先判断轨迹是否正在上传，若还在上传，则先不进行上传动作，继续累加坐标点
                if (mTraceList.size() >= 30 && !start_up) {
                    //轨迹纠偏
                    L.d("-------开始纠偏--------");
                    start_up = true;
                    mTraceList.add(traceLocation);
                    alterTrance(new ArrayList<TraceLocation>(mTraceList));

                    // UpLoadLocation();
                } else if (start_up) {
                    mPrepareLatLngs.add(traceLocation);
                } else {
                    if (mPrepareLatLngs.size() > 0 && mPrepareLatLngs.get(mPrepareLatLngs.size() - 1).getTime() < traceLocation.getTime()) {
                        mTraceList.addAll(mPrepareLatLngs);
                        mPrepareLatLngs.clear();
                    }
                    mTraceList.add(traceLocation);
                }
            }
        }
//        NetHelper.UpMyLocation(latitude, longitude, this);
    }

    private void alterTrance(final List<TraceLocation> trace) {
        mLbsTraceClient.queryProcessedTrace(TRACE_ID, trace, LBSTraceClient.TYPE_AMAP, new TraceListener() {
            @Override
            public void onRequestFailed(int i, String s) {
                L.d("ProcessedTrace-------mTraceList.size():" + trace.size() + "onRequestFailed-------失败信息：" + s);
                start_up = false;
            }

            /**
             *
             * @param lineID 用于标示一条轨迹，支持多轨迹纠偏，如果多条轨迹调起纠偏接口，则lineID需不同。
             * @param index 条轨迹分割为多个段,标示当前轨迹段索引。
             * @param list
             */
            @Override
            public void onTraceProcessing(int lineID, int index, List<LatLng> list) {
//                start_up = false;
                L.d("ProcessedTrace-------mTraceList.size():" + trace.size() + "开纠偏完成onTraceProcessing-------得到数据个数：" + list.size());
                mPolyoptions.addAll(list);

                mView.onDrawLine(mPolyoptions);
                L.d("ProcessedTrace-------mTraceList.size():" + mTraceList.size() + "开纠偏完成onFinished-------得到数据个数：" + list.size());
                ToastUtil.showToastShort(Factory.app(), "得到纠偏的数据，共有" + list.size());
                //纠偏完成，开始上传
                UpLoadLocation(list);
            }

            /**
             *
             * @param lineID 用于标示一条轨迹，支持多轨迹纠偏，如果多条轨迹调起纠偏接口，则lineID需不同。
             * @param list 整条轨迹经过纠偏后点的经纬度集合。
             * @param distance 轨迹经过纠偏后总距离，单位米。
             * @param waitingtime 该轨迹中间停止时间，以GPS速度为参考，单位秒。
             */
            @Override
            public void onFinished(int lineID, List<LatLng> list, int distance, int waitingtime) {
//                mPolyoptions.addAll(list);
//
//                mView.onDrawLine(mPolyoptions);
//                L.d("ProcessedTrace-------mTraceList.size():" + mTraceList.size() + "开纠偏完成onFinished-------得到数据个数：" + list.size());
//                ToastUtil.showToastShort(Factory.app(),"得到纠偏的数据，共有"+list.size());
//                //纠偏完成，开始上传
//                UpLoadLocation(list);
//                mTraceList.clear();
//                mTraceList.clear();
//                start_up = false;
            }
        });
    }


    //上传网络
    private void UpLoadLocation(List<LatLng> list) {
        //开始纠偏
//        PathSmoothTool tool = new PathSmoothTool();
//        tool.setIntensity(4);
//        List<LatLng> latLngs = tool.pathOptimize(mNewLatLngs);
        if (list != null && list.size() > 0) {
            TraceListEntity entity = new TraceListEntity();
            entity.coordinates = new ArrayList<>();
            for (LatLng latLng : list) {
                TraceListEntity.Coordinates coordinates = new TraceListEntity.Coordinates();
                coordinates.latitude = latLng.latitude;
                coordinates.longitude = latLng.longitude;
                coordinates.dataTime = System.currentTimeMillis();
                entity.coordinates.add(coordinates);
            }
            entity.isEnd = "0";
            entity.userId = SPEngine.getSPEngine().getUserInfo().getUser_id();
            mEntities.coordinates.addAll(entity.coordinates);
//            NetHelper.UpTrance(entity, this);
        }
    }

    @Override
    public void onDataLoaded(BaseEntity data, int reqId) {
        mTraceList.clear();
        start_up = false;
    }

    @Override
    public void onDataNotAvailable(String strRes, int reqId) {
        start_up = false;
    }

    @Override
    public void destroy() {
        super.destroy();
        ForWrite();
    }

    private void ForWrite() {
        File externalStorageDirectory = Environment.getExternalStorageDirectory();
        File file = new File(externalStorageDirectory, "/TraceRecord");
        int i = 0;
        String extName = ".txt";
        File recordFiles = new File(file, "recordTraceT" + i + extName);
        while (FileUtils.isFileExists(recordFiles)) {
            i++;
            recordFiles = new File(file, "recordTraceT" + i + extName);
        }

        ObjectOutputStream oos = null;

        try {
            oos = new ObjectOutputStream(new FileOutputStream(recordFiles));
            oos.writeObject(mEntities);
            mLatLngList.clear();
            oos.close();
        } catch (Exception e) {

        }
    }


}
